package com.xianyuwangyou.taizhangdengji

import android.content.Context
import android.os.Build
import android.os.Environment
import android.util.Log
import org.apache.commons.net.ftp.FTP
import org.apache.commons.net.ftp.FTPClient
import org.apache.commons.net.ftp.FTPReply
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException

/**
 * FTP同步管理类
 * 负责处理与FTP服务器的数据同步操作
 */
class FTPSyncManager private constructor() {
    private val TAG = "FTPSyncManager"
    
    companion object {
        @Volatile
        private var INSTANCE: FTPSyncManager? = null

        fun getInstance(): FTPSyncManager {
            return INSTANCE ?: synchronized(this) {
                INSTANCE ?: FTPSyncManager().also { INSTANCE = it }
            }
        }
    }
    
    /**
     * FTP配置数据类
     */
    data class FTPConfig(
        val server: String,
        val port: Int,
        val username: String,
        val password: String,
        val remotePath: String = "/"
    )
    
    /**
     * 同步结果回调接口
     */
    interface SyncCallback {
        fun onSuccess(message: String)
        fun onError(error: String)
    }
    
    /**
     * 从应用外部存储获取数据文件路径
     */
    private fun getExternalDataFile(context: Context): File {
        // 使用现代方式获取外部存储目录，适配Android 10及以上版本
        val externalDir = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            // 在Android 10及以上版本中，使用外部公共目录确保数据持久性
            val externalPublicDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)
            File(externalPublicDir, "TaizhangDengji")
        } else {
            // Android 9及以下版本
            File(Environment.getExternalStorageDirectory(), "TaizhangDengji")
        }
        
        if (!externalDir.exists()) {
            externalDir.mkdirs()
        }
        return File(externalDir, "data.json")
    }
    
    /**
     * 从应用外部存储获取配置文件路径
     */
    private fun getExternalConfigFile(context: Context): File {
        // 使用现代方式获取外部存储目录，适配Android 10及以上版本
        val externalDir = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            // 在Android 10及以上版本中，使用外部公共目录确保数据持久性
            val externalPublicDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)
            File(externalPublicDir, "TaizhangDengji")
        } else {
            // Android 9及以下版本
            File(Environment.getExternalStorageDirectory(), "TaizhangDengji")
        }
        
        if (!externalDir.exists()) {
            externalDir.mkdirs()
        }
        return File(externalDir, "config.json")
    }
    
    /**
     * 连接到FTP服务器
     */
    private fun connectToFTP(config: FTPConfig): FTPClient? {
        val ftpClient = FTPClient()
        try {
            // 连接到FTP服务器
            ftpClient.connect(config.server, config.port)
            
            // 检查连接响应
            val reply = ftpClient.replyCode
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftpClient.disconnect()
                Log.e(TAG, "FTP服务器拒绝连接")
                return null
            }
            
            // 登录
            if (!ftpClient.login(config.username, config.password)) {
                Log.e(TAG, "FTP登录失败")
                return null
            }
            
            // 设置文件传输类型为二进制
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE)
            
            // 进入被动模式
            ftpClient.enterLocalPassiveMode()
            
            // 切换到指定目录
            if (config.remotePath != "/" && !ftpClient.changeWorkingDirectory(config.remotePath)) {
                Log.w(TAG, "无法切换到指定目录: ${config.remotePath}")
            }
            
            return ftpClient
        } catch (e: IOException) {
            Log.e(TAG, "连接FTP服务器时发生错误", e)
            try {
                ftpClient.disconnect()
            } catch (disconnectException: IOException) {
                Log.e(TAG, "断开FTP连接时发生错误", disconnectException)
            }
            return null
        }
    }
    
    /**
     * 上传文件到FTP服务器
     */
    fun uploadToFTP(context: Context, config: FTPConfig, callback: SyncCallback) {
        Thread {
            var ftpClient: FTPClient? = null
            try {
                // 连接到FTP服务器
                ftpClient = connectToFTP(config)
                if (ftpClient == null) {
                    callback.onError("无法连接到FTP服务器")
                    return@Thread
                }
                
                // 获取本地数据文件
                val dataFile = getExternalDataFile(context)
                val configFile = getExternalConfigFile(context)
                
                if (!dataFile.exists() && !configFile.exists()) {
                    callback.onError("本地没有找到需要同步的数据文件")
                    return@Thread
                }
                
                var uploadedCount = 0
                
                // 上传数据文件
                if (dataFile.exists()) {
                    val dataInputStream = FileInputStream(dataFile)
                    if (ftpClient.storeFile("data.json", dataInputStream)) {
                        uploadedCount++
                    } else {
                        Log.e(TAG, "上传data.json失败")
                    }
                    dataInputStream.close()
                }
                
                // 上传配置文件
                if (configFile.exists()) {
                    val configInputStream = FileInputStream(configFile)
                    if (ftpClient.storeFile("config.json", configInputStream)) {
                        uploadedCount++
                    } else {
                        Log.e(TAG, "上传config.json失败")
                    }
                    configInputStream.close()
                }
                
                callback.onSuccess("成功上传 $uploadedCount 个文件到FTP服务器")
            } catch (e: Exception) {
                Log.e(TAG, "上传到FTP失败", e)
                callback.onError("上传失败: ${e.message}")
            } finally {
                try {
                    ftpClient?.logout()
                    ftpClient?.disconnect()
                } catch (e: IOException) {
                    Log.e(TAG, "断开FTP连接时发生错误", e)
                }
            }
        }.start()
    }
    
    /**
     * 从FTP服务器下载文件
     */
    fun downloadFromFTP(context: Context, config: FTPConfig, callback: SyncCallback) {
        Thread {
            var ftpClient: FTPClient? = null
            try {
                // 连接到FTP服务器
                ftpClient = connectToFTP(config)
                if (ftpClient == null) {
                    callback.onError("无法连接到FTP服务器")
                    return@Thread
                }
                
                // 获取本地数据文件路径
                val dataFile = getExternalDataFile(context)
                val configFile = getExternalConfigFile(context)
                
                var downloadedCount = 0
                
                // 下载数据文件
                try {
                    val dataOutputStream = FileOutputStream(dataFile)
                    if (ftpClient.retrieveFile("data.json", dataOutputStream)) {
                        downloadedCount++
                    } else {
                        Log.e(TAG, "下载data.json失败")
                    }
                    dataOutputStream.close()
                } catch (e: Exception) {
                    Log.w(TAG, "下载data.json失败", e)
                }
                
                // 下载配置文件
                try {
                    val configOutputStream = FileOutputStream(configFile)
                    if (ftpClient.retrieveFile("config.json", configOutputStream)) {
                        downloadedCount++
                    } else {
                        Log.e(TAG, "下载config.json失败")
                    }
                    configOutputStream.close()
                } catch (e: Exception) {
                    Log.w(TAG, "下载config.json失败", e)
                }
                
                callback.onSuccess("成功从FTP服务器下载 $downloadedCount 个文件")
            } catch (e: Exception) {
                Log.e(TAG, "从FTP下载失败", e)
                callback.onError("下载失败: ${e.message}")
            } finally {
                try {
                    ftpClient?.logout()
                    ftpClient?.disconnect()
                } catch (e: IOException) {
                    Log.e(TAG, "断开FTP连接时发生错误", e)
                }
            }
        }.start()
    }
    
    /**
     * 同步数据到FTP服务器（先上传后下载）
     */
    fun syncWithFTP(context: Context, config: FTPConfig, callback: SyncCallback) {
        // 先上传本地数据
        uploadToFTP(context, config, object : SyncCallback {
            override fun onSuccess(message: String) {
                // 上传成功后再下载服务器数据
                downloadFromFTP(context, config, object : SyncCallback {
                    override fun onSuccess(message: String) {
                        callback.onSuccess("同步完成: $message")
                    }
                    
                    override fun onError(error: String) {
                        callback.onError("下载失败: $error")
                    }
                })
            }
            
            override fun onError(error: String) {
                callback.onError("上传失败: $error")
            }
        })
    }
}